-
Notifications
You must be signed in to change notification settings - Fork 26
Updating DLC-Live! GUI to pyside6 and multicamera support #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Updating DLC-Live! GUI to pyside6 and multicamera support #35
Conversation
…modern-python-and-pyqt6 Add Basler and GenTL camera backends for modular capture
…era-functionality
…camera-functionality Rework layout and camera handling controls
…' into artur/test_update
…r integration - Implemented `get_device_count` method in `GenTLCameraBackend` to retrieve the number of GenTL devices detected. - Added `max_devices` configuration option in `CameraSettings` to limit device probing. - Introduced `BoundingBoxSettings` for bounding box visualization, integrated into the main GUI. - Enhanced `DLCLiveProcessor` to accept a processor instance during configuration. - Updated GUI to support processor selection and auto-recording based on processor commands. - Refactored camera properties handling and removed deprecated advanced properties editor. - Improved error handling and logging for processor connections and recording states.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… options to config
- Update configuration settings to include support for single-animal models in DLCProcessorSettings. - Improve user guide with a link to DLC documentation for model export.
…le_animal in DLCLiveProcessor settings
- Implemented MultiCameraController to manage multiple cameras simultaneously.
…fix for basler backend
…me data without tiling and track source camera ID
…ulti-camera controller
deruyter92
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturoptophys, great PR! I think this is going to be super helpful.
I think we should aim to merge as soon as DeepLabCut-live 1.2 release is official. This PR is getting quite big already.
Let me know if you want me to look at specific components that you are unsure of / need help with.
Ofc it would be great to add some testing as well..
| """Setup configuration for the DeepLabCut Live GUI.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import setuptools | ||
|
|
||
| with open("README.md", "r") as fh: | ||
| with open("README.md", "r", encoding="utf-8") as fh: | ||
| long_description = fh.read() | ||
|
|
||
| setuptools.setup( | ||
| name="deeplabcut-live-gui", | ||
| version="1.0", | ||
| version="2.0", | ||
| author="A. & M. Mathis Labs", | ||
| author_email="adim@deeplabcut.org", | ||
| description="GUI to run real time deeplabcut experiments", | ||
| description="PySide6-based GUI to run real time DeepLabCut experiments", | ||
| long_description=long_description, | ||
| long_description_content_type="text/markdown", | ||
| url="https://github.com/DeepLabCut/DeepLabCut-live-GUI", | ||
| python_requires=">=3.5, <3.11", | ||
| python_requires=">=3.10", | ||
| install_requires=[ | ||
| "deeplabcut-live", | ||
| "pyserial", | ||
| "pandas", | ||
| "tables", | ||
| "multiprocess", | ||
| "imutils", | ||
| "pillow", | ||
| "tqdm", | ||
| "PySide6", | ||
| "numpy", | ||
| "opencv-python", | ||
| "vidgear[core]", | ||
| ], | ||
| extras_require={ | ||
| "basler": ["pypylon"], | ||
| "gentl": ["harvesters"], | ||
| }, | ||
| packages=setuptools.find_packages(), | ||
| include_package_data=True, | ||
| classifiers=( | ||
| "Programming Language :: Python :: 3", | ||
| "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", | ||
| "Operating System :: OS Independent", | ||
| ), | ||
| entry_points={ | ||
| "console_scripts": [ | ||
| "dlclivegui=dlclivegui.dlclivegui:main", | ||
| "dlclivegui-video=dlclivegui.video:main", | ||
| "dlclivegui=dlclivegui.gui:main", | ||
| ] | ||
| }, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think setup.py should be removed. All information is in pyproject.toml now, and having this duplicated list of dependencies here is only confusing (or potentially conflicting). Setuptools works perfectly fine without setup.py now, since you made the pyproject.toml PEP 517 / 518 / 621–compliant.
You could keep only the following code if you want:
| from setuptools import setup | |
| # Only kept for compatibility with external legacy tools. | |
| # All information is now in pyproject.toml. | |
| setup() |
| # Install with gentl support | ||
| pip install deeplabcut-live-gui[gentl] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also add basler here:
| # Install with gentl support | |
| pip install deeplabcut-live-gui[gentl] | |
| # Install with gentl support | |
| pip install deeplabcut-live-gui[gentl] | |
| # Install with basler support | |
| pip install deeplabcut-live-gui[basler] |
| # Install with gentl support | ||
| pip install deeplabcut-live-gui[gentl] | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an additional block on how to install from source:
Editable Installation from Source (for contributors or advanced users)
- Clone the repository
git clone https://github.com/DeepLabCut/DeepLabCut-live-GUI.git
cd DeepLabCut-live-GUI- Install editable package using pip or the uv package manager
# Using pip
pip install -e .
# Or using uv
uv sync| 2. **Select Camera Backend**: Choose from the dropdown (opencv, gentl, aravis, basler) | ||
|
|
||
| #### Processor (optional) | ||
| 3. **Configure Camera**: Set FPS, exposure, gain, and other parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is not updated for the multi-camera setup yet, is it?
| The GUI supports PyTorch DLCLive models: | ||
|
|
||
| If you would not like to save the data from the session, please click `Delete Video`, and all data will be discarded. After you click `Save Video` or `Delete Video`, the `Off` button will be selected, indicating you can now set up a new session. | ||
| 1. **PyTorch**: PyTorch-based models (requires PyTorch installation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally the Pytorch dependency is automatically handled by DeepLabCut-live to avoid issues.
| ] | ||
|
|
||
| dependencies = [ | ||
| "deeplabcut-live", # might be missing timm and scipy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's specify this minimal version (old version is incompatible). And let's have the PyTorch dependency handled by deeplabcut-live (installs scipy, timm and torch automatically).
| "deeplabcut-live", # might be missing timm and scipy | |
| "deeplabcut-live[pytorch] >= 1.1.0" |
NOTE: the required deeplabcut-live version is not officially released yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on my windows machine the current dlclive3 branch installed with [pytorch] flag does not install cuda-compiled version of pytorch i had to manually install pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu130
| LOGGER.exception("Pose inference failed", exc_info=exc) | ||
| self.error.emit(str(exc)) | ||
| finally: | ||
| self._queue.task_done() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I encountered this race condition: when stopping, _stop_worker() sets self._queue = None (line 236) while the worker thread is in the finally block. (I think..?)
| self._queue.task_done() | |
| if self._queue is not None: | |
| self._queue.task_done() |
| save_dict = self.get_data() | ||
| path2save = Path(__file__).parent.parent.parent / "data" / file | ||
| LOG.info(f"Path should be {path2save}") | ||
| pickle.dump(save_dict, open(path2save, "wb")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs context manager?
| pickle.dump(save_dict, open(path2save, "wb")) | |
| with path2save.open("wb") as f: | |
| pickle.dump(save_dict, f) |
| text = value.strip() | ||
| if not text: | ||
| return {} | ||
| return json.loads(text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add error handling:
| return json.loads(text) | |
| try: | |
| return json.loads(text) | |
| except json.JSONDecodeError as e: | |
| logging.warning(f"Invalid JSON in additional options: {e}. Using empty dict.") | |
| return {} |
| is_dlc_camera_frame = frame_data.source_camera_id == dlc_cam_id | ||
|
|
||
| # Update tile info and raw frame only when DLC camera frame arrives | ||
| if is_dlc_camera_frame and dlc_cam_id in frame_data.frames: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could fail if dlc_cam_id is None
| if is_dlc_camera_frame and dlc_cam_id in frame_data.frames: | |
| if is_dlc_camera_frame and dlc_cam_id is not None and dlc_cam_id in frame_data.frames: |
|
@deruyter92 @arturoptophys See #36 for ongoing end-to-end GUI testing efforts |
This PR supercedes the #34
Compared to the previos PR this: